package org.yzh.scheduler.service;

import jakarta.annotation.PostConstruct;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yzh.scheduler.mapper.JobLogMapper;
import org.yzh.scheduler.mapper.ScheduleJobMapper;
import org.yzh.scheduler.model.entity.JobLogDO;
import org.yzh.scheduler.model.entity.ScheduleJobDO;
import org.yzh.scheduler.schedule.SchedulerManager;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class ScheduleJobService {

    @Autowired
    private ScheduleJobMapper scheduleJobMapper;

    @Autowired
    private JobLogMapper jobLogMapper;

    @Autowired
    private SchedulerManager schedulerManager;

    @PostConstruct
    public void initialJob() throws SchedulerException {
        List<ScheduleJobDO> jobs = scheduleJobMapper.find(null, null, false);
        if (jobs.isEmpty())
            return;

        for (ScheduleJobDO job : jobs) {

            if (schedulerManager.checkExists(job.getJobName(), job.getJobGroup()))
                schedulerManager.updateCron(job.getJobName(), job.getJobGroup(), job.getCronExpression());
            else
                schedulerManager.createJob(job.getJobName(), job.getJobGroup(), job.getCronExpression());
        }
    }

    public String[] groupNames() {
        return scheduleJobMapper.groupNames();
    }

    public List<ScheduleJobDO> find(String name, String group, Boolean disabled) throws SchedulerException {
        List<ScheduleJobDO> jobs = scheduleJobMapper.find(name, group, disabled);

        for (ScheduleJobDO t : jobs) {
            t.setJobLog(jobLogMapper.getLately(t.getJobName(), t.getJobGroup()));
            t.setState(schedulerManager.getTriggerState(t.getJobName(), t.getJobGroup()));
        }
        return jobs;
    }

    public void add(ScheduleJobDO job) throws SchedulerException {
        int row = scheduleJobMapper.insert(job);
        if (row > 0)
            schedulerManager.createJob(job.getJobName(), job.getJobGroup(), job.getCronExpression());
    }

    public void update(ScheduleJobDO job) throws SchedulerException {
        int row = scheduleJobMapper.update(job);
        if (row > 0)
            schedulerManager.updateCron(job.getJobName(), job.getJobGroup(), job.getCronExpression());
    }

    public void delete(String name, String group) throws SchedulerException {
        int row = scheduleJobMapper.delete(name, group);
        if (row > 0)
            schedulerManager.delete(name, group);
    }

    public void runOnce(String name, String group) throws SchedulerException {
        schedulerManager.runOnce(name, group);
    }

    public void pause(String name, String group) throws SchedulerException {
        schedulerManager.pauseJob(name, group);
    }

    public void resume(String name, String group) throws SchedulerException {
        schedulerManager.resumeJob(name, group);
    }

    public List<JobLogDO> findLog(String name, String group, LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        return jobLogMapper.find(name, group, startTime, endTime, limit);
    }

    public void callback(JobLogDO key, String message) {
        JobLogDO jobLog = jobLogMapper.get(key.getId());

        if (jobLog.getCallbackTime() == null) {

            jobLog.setCallbackCode(200);
            jobLog.setCallbackMsg(message);
            jobLog.setCallbackTime(LocalDateTime.now());

            jobLogMapper.update(jobLog);
        }
    }
}